package com.neusoft.neuiotms.dcom.converter.hn;

import java.util.List;
import java.util.stream.Collectors;

import org.activiti.editor.language.json.converter.util.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.web.dto.AbstractConverter;
import com.neusoft.bizcore.web.utils.id.BaseIdGenerator;
import com.neusoft.neuiotms.dcom.dto.hn.HnInspectionTaskDTO;
import com.neusoft.neuiotms.dcom.model.enums.HnInspectionTaskItemStatus;
import com.neusoft.neuiotms.dcom.model.hn.HnInspectionTask;
import com.neusoft.neuiotms.dcom.model.hn.HnInspectionTaskAsset;
import com.neusoft.neuiotms.dcom.model.hn.HnInspectionTaskItemValue;
import com.neusoft.neuiotms.dcom.repository.hn.HnInspectionTaskAssetRepository;
import com.neusoft.neuiotms.dcom.repository.hn.HnInspectionTaskItemValueRepository;
import com.neusoft.neuiotms.dcom.repository.hn.HnInspectionTaskRepository;

@Component
public class HnInspectionTaskConverter extends AbstractConverter<HnInspectionTask, HnInspectionTaskDTO> {

    @Autowired
    private HnInspectionTaskRepository hnInspectionTaskRepository;
    @Autowired
    private BaseIdGenerator hnInspectionTaskCodeGenerator;
    @Autowired
    private HnInspectionTaskAssetRepository hnInspectionTaskAssetRepository;
    @Autowired
    private HnInspectionTaskAssetConverter hnInspectionTaskAssetConverter;
    @Autowired
    private HnInspectionTaskItemValueRepository hnInspectionTaskItemValueRepository;
    @Autowired
    private HnInspectionTaskItemValueConverter hnInspectionTaskItemValueConverter;

    @Override
    public HnInspectionTask toModel(final HnInspectionTaskDTO dto) {
        HnInspectionTask model;
        if (dto.isNew()) {
            model = new HnInspectionTask();
        } else {
            model = this.hnInspectionTaskRepository.getOne(dto.getId());
        }
        model.setCode(StringUtils.isNotBlank(dto.getCode()) ? dto.getCode()
                : this.hnInspectionTaskCodeGenerator.generateCode());
        model.setActualDateTime(dto.getActualDateTime());
        final List<HnInspectionTaskAsset> assets = model.getAssets().stream().collect(Collectors.toList());
        assets.forEach(t -> {
            model.getAssets().remove(t);
            this.hnInspectionTaskAssetRepository.delete(t);
        });
        if (CollectionUtils.isNotEmpty(dto.getAssets())) {
            dto.getAssets().stream().map(t -> {
                final HnInspectionTaskAsset asset = this.hnInspectionTaskAssetConverter.toModel(t);
                asset.setTask(model);
                return asset;
            }).forEach(model.getAssets()::add);

            model.setOnlineCount(model.getAssets().stream().filter(it -> it.isOnline()).count());
        }
        model.setEndDateTime(dto.getEndDateTime());
        //        model.setHnInspectionPlan();
        model.setStartDateTime(dto.getStartDateTime());
        model.setUserCode(dto.getUserCode());
        model.setUserName(dto.getUserName());
        model.setInstitutionCode(dto.getInstitutionCode());
        model.setInstitutionName(dto.getInstitutionName());
        model.setProblem(dto.getProblem());
        model.setSolution(dto.getSolution());

        final List<HnInspectionTaskItemValue> items = model.getItemValues().stream().collect(Collectors.toList());
        items.forEach(t -> {
            model.getItemValues().remove(t);
            this.hnInspectionTaskItemValueRepository.delete(t);
        });
        if (CollectionUtils.isNotEmpty(dto.getItemValues())) {
            dto.getItemValues().stream().map(t -> {
                final HnInspectionTaskItemValue value = this.hnInspectionTaskItemValueConverter.toModel(t);
                value.setTask(model);
                return value;
            }).forEach(model.getItemValues()::add);

            if (model.getItemValues().stream().filter(it -> it.getStatus().equals(HnInspectionTaskItemStatus.alarm))
                    .findAny().isPresent()) {
                model.setItemStatus(HnInspectionTaskItemStatus.alarm);
            } else {
                model.setItemStatus(HnInspectionTaskItemStatus.normal);
            }
        } else {
            model.setItemStatus(HnInspectionTaskItemStatus.uninspected);
        }
        model.setUpdateTime(dto.getUpdateTime());
        model.setStatus(dto.getStatus());

        return model;
    }

    @Override
    public HnInspectionTaskDTO toDTO(final HnInspectionTask model, final boolean forListView) {
        final HnInspectionTaskDTO dto = new HnInspectionTaskDTO();
        dto.setCode(model.getCode());
        dto.setCreateTime(model.getCreateTime());
        dto.setEndDateTime(model.getEndDateTime());
        dto.setId(model.getId());
        dto.setStartDateTime(model.getStartDateTime());
        dto.setInstitutionCode(model.getInstitutionCode());
        dto.setInstitutionName(model.getInstitutionName());
        dto.setUpdateTime(model.getUpdateTime());
        dto.setUserCode(model.getUserCode());
        dto.setUserName(model.getUserName());
        dto.setActualDateTime(model.getActualDateTime());
        dto.setAssets(this.hnInspectionTaskAssetConverter.toListDTO(model.getAssets()));
        dto.setItemValues(this.hnInspectionTaskItemValueConverter.toListDTO(model.getItemValues()));
        dto.setProblem(model.getProblem());
        dto.setSolution(model.getSolution());
        dto.setStatus(model.getStatus());
        dto.setItemStatus(model.getItemStatus());
        dto.setOnlineCount(model.getOnlineCount());
        return dto;
    }

}
